package com.dense.kuiniu.floatcabinet.mvp.presenter;

import android.util.Log;
import android.util.SparseArray;

import com.dense.kuiniu.floatcabinet.mvp.contract.HomeContract;
import com.dense.kuiniu.floatcabinet.mvp.event.BackResultEvent;
import com.dense.kuiniu.floatcabinet.mvp.event.BorrowResultEvent;
import com.dense.kuiniu.floatcabinet.mvp.event.DoorOpenOrCloseEvent;
import com.dense.kuiniu.floatcabinet.mvp.event.InventoryResultEvent;
import com.dense.kuiniu.floatcabinet.mvp.http.entity.AdminBean;
import com.dense.kuiniu.floatcabinet.mvp.http.entity.BaseResponse;
import com.dense.kuiniu.floatcabinet.mvp.http.entity.Book;
import com.dense.kuiniu.floatcabinet.mvp.http.entity.Inventory;
import com.dense.kuiniu.floatcabinet.mvp.http.entity.Reader;
import com.dense.kuiniu.floatcabinet.mvp.http.post.BorrowOrBackBody;
import com.dense.kuiniu.floatcabinet.mvp.http.post.InventoryBody;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.Door;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.DoorManager;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.IAction;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.IMessage;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.MessageCenter;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.MessageObserver;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.Task;
import com.dense.kuiniu.floatcabinet.mvp.manager.bord.TaskManager;
import com.dense.kuiniu.floatcabinet.mvp.model.AuthenticationModel;
import com.dense.kuiniu.floatcabinet.mvp.model.BusinessModel;
import com.dense.kuiniu.floatcabinet.utils.RxUtils;
import com.jess.arms.integration.EventBusManager;
import com.jess.arms.mvp.BasePresenter;
import com.jess.arms.mvp.IModel;

import org.greenrobot.eventbus.EventBus;

import java.util.List;

import javax.inject.Inject;

import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import me.jessyan.rxerrorhandler.handler.RetryWithDelay;
import timber.log.Timber;

/**
 * @author Administrator
 * @date 2020/9/28
 */
public class HomePresenter extends BasePresenter<IModel,
        HomeContract.View> implements IMessage {
    private RxErrorHandler rxErrorHandler;
    @Inject
    AuthenticationModel authenticationModel;
    @Inject
    BusinessModel businessModel;
    private IAction mIAction;
    private MessageObserver mObserver;
    private TaskManager mTaskManager;

    @Inject
    public HomePresenter(HomeContract.View rootView,
                         RxErrorHandler rxErrorHandler) {
        super(rootView);
        this.rxErrorHandler = rxErrorHandler;
        mTaskManager = new TaskManager();
    }


    public void adminLogin(String user, String password) {
        authenticationModel.adminLogin(user, password)
                .compose(RxUtils.applySchedulers(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResponse<AdminBean>>(rxErrorHandler) {
                    @Override
                    public void onNext(BaseResponse<AdminBean> response) {
                        if (response.isSuccess()) {
                            mRootView.adminLoginResult(response.getData());
                        } else {
                            mRootView.showMessage(response.getMsg());
                        }
                    }
                });
    }

    public void authentication(String account, Class<?> cls) {
        if (account != null && !account.isEmpty()) {
            authenticationModel.readerAuthentication(account, "")
                    .compose(RxUtils.applySchedulers(mRootView))
                    .subscribe(new ErrorHandleSubscriber<BaseResponse<Reader>>(rxErrorHandler) {
                        @Override
                        public void onNext(BaseResponse<Reader> response) {
                            if (response.isSuccess()) {
                                mRootView.authentication(response.getData(), cls);
                            } else {
                                mRootView.showMessage(response.getMsg());
                            }
                        }
                    });
        }
    }

    public void startExecuteUnfinishedTask() {
        DoorManager.getInstance().init();
        mIAction.initDoorStatus(1);
        //mIAction.initDoorStatus(2);
        //executeNotFinishTask();
    }

    public void back(String cardNo) {
        Door door = DoorManager.getInstance().findLeastDataDoor();
        if (door != null) {
            openDoor(cardNo, door.getDoorNumber(), 1);
        }
    }


    public void openDoor(String account, int doorNumber, int countType) {
        mTaskManager.addRunTask(account, doorNumber, countType);
        mIAction.open(doorNumber);
        //触发执行未完成的任务
        executeNotFinishTask();
    }

    public void scan(String account, int doorNumber) {
//        if (!mTaskManager.addRunTask(account, doorNumber, 2)) {
        Log.e("scan", "scan");
        mIAction.inventorySingle(doorNumber);
//        } else {
//            //触发执行未完成的任务
//            executeNotFinishTask();
//        }
    }


    @Override
    public void doorChange(List<Door> openList, List<Door> closeList) {
        EventBus.getDefault().postSticky(new DoorOpenOrCloseEvent(openList, closeList));
    }


    @Override
    public void changeList(int doorNumber, List<String> reduction,
                           List<String> increase,
                           List<String> epcList) {
        Task task = mTaskManager.getRunTask(doorNumber);
        if (task != null) {
            Timber.e("有借还书任务，账号为=" + task.getAccount() + ",门号为=" + task.getDoorNumber());
            task.setReduction(reduction);
            task.setIncrease(increase);
        } else {
            Timber.e("仅仅是盘点,门号为=%s", doorNumber);
            task = new Task("123", doorNumber, 2);
        }
        task.setEpcList(epcList);
        sendChange(task);
    }

    @Override
    public void initDoorState(int deviceId, byte[] status) {
        DoorManager.getInstance().initDoorState(deviceId, status);
        //盘点
        mIAction.inventoryAll();
    }

    /**
     * 取出未完成的任务执行
     */
    private void executeNotFinishTask() {
        SparseArray<Task> allTask = mTaskManager.getAllTask();
        for (int i = 0; i < allTask.size(); i++) {
            sendChange(allTask.valueAt(i));
        }
    }

    private void sendChange(Task task) {
        List<String> reduction = task.getReduction();
        if (reduction != null && !reduction.isEmpty()) {
            BorrowOrBackBody borrow = new BorrowOrBackBody(task.getAccount(), task.getDoorNumber(),
                    "8", reduction);
            businessModel.borrow(borrow)
                    .retryWhen(new RetryWithDelay(3, 3))
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .subscribe(new ErrorHandleSubscriber<BaseResponse<Reader>>(rxErrorHandler) {
                        @Override
                        public void onNext(BaseResponse<Reader> response) {
                            Reader reader = response.getData();
                            EventBusManager.getInstance().post(new BorrowResultEvent(task.getAccount(),
                                    reader.getBookList()));
                            //更新数据库
                            task.setReduction(null);
                            checkNeedDelete(task);
                        }
                    });
        }
        List<String> increase = task.getIncrease();
        if (increase != null && !increase.isEmpty()) {
            BorrowOrBackBody back = new BorrowOrBackBody(task.getAccount(), task.getDoorNumber(),
                    "8", increase);
            businessModel.back(back)
                    .retryWhen(new RetryWithDelay(3, 3))
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .subscribe(new ErrorHandleSubscriber<BaseResponse<List<Book>>>(rxErrorHandler) {
                        @Override
                        public void onNext(BaseResponse<List<Book>> response) {
                            EventBusManager.getInstance().post(new BackResultEvent(task.getAccount(),
                                    response.getData()));
                            //更新数据库
                            task.setIncrease(null);
                            checkNeedDelete(task);
                        }
                    });
        }
        List<String> epcList = task.getEpcList();
        if (epcList != null && !epcList.isEmpty()) {
            Timber.e("同步盘点数据到后台，门号=%s", task.getDoorNumber());
            DoorManager.getInstance().updateDoorEpcListData(task.getDoorNumber(), epcList);
            InventoryBody inventoryBody = new InventoryBody(task.getAccount(), task.getDoorNumber(),
                    "8", epcList);
            businessModel.inventory(inventoryBody).
                    subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .subscribe(new ErrorHandleSubscriber<BaseResponse<Inventory>>(rxErrorHandler) {
                        @Override
                        public void onNext(BaseResponse<Inventory> response) {
                            EventBusManager.getInstance().post(new InventoryResultEvent(task.getAccount(),
                                    task.getDoorNumber(), task.getEpcList()));
                            task.setEpcList(null);
                            checkNeedDelete(task);
                        }
                    });
        }
    }

    private synchronized void checkNeedDelete(Task task) {
        if (task.getReduction() == null && task.getIncrease() == null
                && task.getEpcList() == null) {
            mTaskManager.removeRunTask(task.getDoorNumber());
        }
    }

    private void registerObserver() {
        mObserver = new MessageObserver();
        mObserver.register();
        mIAction = new MessageCenter(this, mObserver);
    }

    private void unRegisterObserver() {
        if (mObserver != null) {
            mObserver.unRegister();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        registerObserver();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unRegisterObserver();
    }
}